package com.example.kotlinstudy.activity.KTBase.stage3

/*
kotlin内置函数讲解
1、apply函数，函数体返回的是this
一般大部分情况下，匿名函数，都会持有一个it，但是apply函数不会持有it，却会持有当前this == info本身
2、let 函数有it，并且函数里面的最后一行作为返回值
  let 和 ?:（空合并操作符）联合使用
  fun getMethod5(value:String?)=value?.let {
                "欢迎回家${it}"
            } ?: "null"
3、run函数（ 函数是一个作用域函数，用于在对象上执行代码块并返回结果）
与 let 的区别
run 使用 this 作为上下文对象，let 使用 it。
run 适合在代码块中直接访问对象属性和方法，let 适合需要明确使用 it 的场景。
具名函数配合run函数:  str.run (::isLong).run (::isLongText).run (::mapTex).run(::println)


5、with函数（和run函数功能差不多，只是写法上有些差异）
  with函数返回类型，是根据匿名函数最后一行的变化而变化 此条和 let一模一样
  with函数的 匿名函数里面持有的是this = str本身    此条和 appLy一楼一样

6、also 函数

7、takeIf函数
// name. takeIf { true/false }
 true：直接返回name本身
 false： 直接放回null
// 小结：一般大部分情况下，都是 takeIf + 空合并操作符=一起使用

8、 takeIf 和 takeUnless功能相反
  // name. takeIf { true/false }
  true：直接放回null
  false：直接返回name本身
  为什么有takeUnless？
 takeUnless+it.isNullorBlank（）一起使用，可以验证字符串有没有初始化等功


6、if语句
Java: if是语句，不能直接返回值。
Kotlin: if是表达式，可以返回值。
val max = if (a > b) a else b

7、具名函数、匿名函数

* */
class KTInnerFunctionsActivity {
    companion object {
        fun applyfun() {
            val info = "Fanxixi Hello"
            val info1 = info.apply {//一般大部分情况下，匿名函数，都会持有一个it，但是apply函数不会持有it，却会持有当前this == info本身
                println("${this.length}")
            }.apply {
                println("${this[length - 1]}")
            }.apply {
                println("${toLowerCase()}")//fanxixi hello
            }.apply {
                println("${capitalize()}")// Fanxixi Hello
            }.apply {
                println("$this")//Fanxixi Hello
            }
            println("${info1}")
        }


        fun letfun() {
            val list = listOf(1, 2, 3, 45, 6)
            val result = list.let {
                it.first() + it.last()
//                true
            }
            println("${result}")//7
            println(getMethod4("fanxixi"))//7
        }

        fun getMethod1(value: String): String {
            return if (value == null) "null" else "欢迎回家"
        }

        fun getMethod4(value: String?): String {
            return value?.let {
                "欢迎回家${it}"
            } ?: "null"
        }

        fun getMethod5(value: String?) = value?.let {
            "欢迎回家${it}"
        } ?: "null"

        fun getMethod2(value: String?): String = if (value == null) "null" else "欢迎回家"

        // kotlin的类型推断
        fun getMethod3(value: String?) = if (value == null) "null" else "欢迎回家"


        /*3、run函数*/
        fun getRun() {
            val str = "Fanxi is OK"
            val result = str.run {
                this.length
                true
            }
            // println(result)//11
            /*demo1:具名函数配合run函数*/
            /*
            匿名函数
             str.run {
            }
             str.run(具名函数)
            * */

            val result2 = str.run(::isLong)//传的就是str，且只能传str
            println(result2)/*true*/


            val result3 = str.run(::isLong).run {
                if (this) "长文本" else "短文本"
            }
            println("result3=" + result3)/*长文本*/


            val result4 = str.run(::isLong).run(::isLongText)
            println("result4=" + result4)/*长文本*/


            val result5 = str.run(::isLong).run(::isLongText).run(::mapTex)
            println("result5=" + result5)/*【长文本】*/

            str.run(::isLong).run(::isLongText).run(::mapTex).run(::println)/*【长文本】*/


            /*demo2:具名函数配合run函数,以上功能用let实现*/
            str.let(::isLong).let(::isLongText).let(::mapTex).let(::println) //【长文本】
        }

        fun isLong(str: String) = if (str.length > 5) true else false
        fun isLongText(isLong: Boolean) = if (isLong) "长文本" else "短文本"
        fun mapTex(str: String) = "【${str}】"

        /*4、with的用法
        * 1.with函数返回类型，是根据匿名函数最后一行的变化而变化 此条和 let一模一样
          2.with函数的 匿名函数里面持有的是this = str本身    此条和 appLy一楼一样
        * */
        fun getWith() {
            val str = "Fanxi is OK"
            val r1 = with(str) {
                if (length > 5) true else false
            }
            val r2 = with(r1) {
                if (this) "长文本" else "短文本"
            }
            println(r2)//长文本

            val r3 = with(r2) {
                "【${str}】"
            }
            println(r3)//长文本 【Fanxi is OK】

            /*具名函数实现*/
            val r4 = with(str, ::isLong)
            val r5 = with(r4, ::isLongText)
            val r6 = with(r5, ::mapTex)
            println(r6)//长文本 【Fanxi is OK】

        }


        /*4、also
      * 1.with函数返回类型，是根据匿名函数最后一行的变化而变化 此条和 let一模一样
        2.with函数的 匿名函数里面持有的是this = str本身    此条和 appLy一楼一样
      * */

        fun getAlso() {
            val info = "Fanxixi Hello"
            val info1 = info.also {//一般大部分情况下，匿名函数，都会持有一个it，但是apply函数不会持有it，却会持有当前this == info本身
                println("${it.length}")
            }.also {
                println("${it[it.length - 1]}")
            }.also {
                println("${it.toLowerCase()}")//fanxixi hello
            }.also {
                println("${it.capitalize()}")// Fanxixi Hello
            }.also {
                println("$this")//Fanxixi Hello
            }
        }

        /*5、takeIf

             * */
        fun getTakeIf() {
            val name = "凡茜茜"
            val r1 = name.takeIf { false }
            println(r1)//null
            //demo1 检查用户是否有权限，有权限输入”欢迎xx用户回家，你拥有超级权限“，否则输出”对不起，你的权限不够！“  用takeif和空合并操作符  实现

            print(checkPermissionName2(name, "124"))
        }

        fun checkPermissionName(username: String, pwd: String): String? {
            return username.takeIf {
                permissionSystem(username, pwd)
            }
        }


        fun checkPermissionName2(username: String, pwd: String): String {
            return username.takeIf {
                permissionSystem(username, pwd)
            } ?: "你的权限不够"
        }

        fun permissionSystem(username: String, pwd: String) = username == "凡茜茜" && pwd === "123"


        /*6、takeUnless内置函数*/
        fun getTakeUnless() {
            val name="王大陆"
            val userName=null
            val r=name.takeUnless { it.isNullOrBlank() } ?:"没有初始化"
            val r2=userName.takeUnless { it.isNullOrBlank() } ?:"没有初始化"
            println(r)//王大陆
            println(r2)//没有初始化
        }

    }


}